# Copyright 2025 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
load("@rules_rust//rust:defs.bzl", "rust_doc", "rust_library")
load("//pw_kernel:flags.bzl", "KERNEL_TEST_DEPS", "KERNEL_TEST_RUSTC_FLAGS")

package(default_visibility = ["//visibility:public"])

bool_flag(
    name = "exceptions_reload_pmp",
    build_setting_default = False,
)

config_setting(
    name = "exceptions_reload_pmp_enabled",
    flag_values = {
        ":exceptions_reload_pmp": "true",
    },
)

rust_library(
    name = "arch_riscv",
    srcs = [
        "disable_interrupts_atomic.rs",
        "exceptions.rs",
        "lib.rs",
        "plic.rs",
        "protection.rs",
        "regs.rs",
        "regs/epmp.rs",
        "regs/pmp.rs",
        "spinlock.rs",
        "threads.rs",
        "timer.rs",
        "timer/clint.rs",
        "timer/mtime.rs",
    ],
    crate_features = ["user_space"] + select({
        "timer_clint": ["timer_clint"],
        "timer_mtime": ["timer_mtime"],
    }) + select({
        "//pw_build/constraints/riscv/extensions:Smepmp": ["epmp"],
        "//conditions:default": [],
    }) + select({
        ":exceptions_reload_pmp_enabled": ["exceptions_reload_pmp"],
        "//conditions:default": [],
    }) + select({
        "//pw_build/constraints/riscv/extensions:A.not": ["disable_interrupts_atomic"],
        "//conditions:default": [],
    }),
    edition = "2024",
    proc_macro_deps = [
        "//pw_kernel/macros:riscv_macro",
        "@rust_crates//:paste",
    ],
    rustc_flags = KERNEL_TEST_RUSTC_FLAGS,
    tags = ["kernel"],
    target_compatible_with = select({
        "@platforms//cpu:riscv32": [],
        "//conditions:default": ["@platforms//:incompatible"],
    }),
    deps = [
        "//pw_kernel/config:kernel_config",
        "//pw_kernel/kernel",
        "//pw_kernel/lib/foreign_box",
        "//pw_kernel/lib/list",
        "//pw_kernel/lib/log_if",
        "//pw_kernel/lib/memory_config",
        "//pw_kernel/lib/pw_assert",
        "//pw_kernel/lib/pw_atomic",
        "//pw_kernel/lib/pw_cast",
        "//pw_kernel/lib/regs",
        "//pw_kernel/lib/time",
        "//pw_kernel/syscall:syscall_defs",
        "//pw_status/rust:pw_status",
        "@pigweed//pw_log/rust:pw_log",
        "@rust_crates//:riscv",
    ] + KERNEL_TEST_DEPS,
)

rust_doc(
    name = "riscv_doc",
    crate = ":arch_riscv",
    rustdoc_flags = [
        "--document-private-items",
        "--cfg=feature=\"user_space\"",
        "--cfg=feature=\"arch_riscv\"",
    ] + select({
        "//pw_build/constraints/riscv/extensions:A.not": ["--cfg=feature=\"disable_interrupts_atomic\""],
        "//conditions:default": [],
    }),
    tags = ["kernel"],
)

constraint_setting(
    name = "timer",
    default_constraint_value = "timer_clint",
)

constraint_value(
    name = "timer_clint",
    constraint_setting = ":timer",
)

constraint_value(
    name = "timer_mtime",
    constraint_setting = ":timer",
)
